/**
 * Copyright (c) 2010-2011 julewa.com.  
 * All rights reserved. 
 * 
 * @author Huang Benhua
 * @date 2011-2-20
 * 
**/
package com.julewa.loading;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Properties;
import java.util.Set;

import com.julewa.utils.ConfigUtils;
import com.julewa.utils.StreamUtils;


@SuppressWarnings("rawtypes")
public final class SystemUtils {
	//
	private static final String SYSTEM_CONF_FILE="system.conf";
    private static final String SYSTEM_PROP_FILE="system.properties";
	private static final String FSEP = System.getProperty("file.separator"); 
    private static String PATH_ROOT = null;
    private static String PATH_CLASSES = null;
    private static String PATH_LIB = null;
    private static Properties properties = new Properties();
    //
    private static boolean debug = false;
    public static void initialize(){
    	boolean isWindows = System.getProperty("os.name").contains("Windows");
    	//
    	ClassLoader classloader = SystemUtils.class.getClassLoader();
    	URL url = classloader.getResource(SYSTEM_PROP_FILE);
    	boolean isConfFile = (url == null);
    	if(isConfFile){
    		url = classloader.getResource(SYSTEM_CONF_FILE);
    	}
    	if(url == null){
    		System.out.println("Configuration file NOT FOUND!");
    		return;
    	}
    	//
    	PATH_CLASSES = "" + url;
    	PATH_CLASSES = PATH_CLASSES.substring(PATH_CLASSES.indexOf(":") + (isWindows?2:1));
    	PATH_CLASSES = PATH_CLASSES.substring(0, 
    			PATH_CLASSES.length() - (isConfFile?SYSTEM_CONF_FILE.length():SYSTEM_PROP_FILE.length()));
    	//
    	if(isWindows)PATH_CLASSES = PATH_CLASSES.replaceAll("%20", " ");
    	//
    	File path = new File(PATH_CLASSES).getParentFile();
    	PATH_ROOT = getStandardPath(path.getParentFile().getAbsolutePath());
    	PATH_LIB = getStandardPath(path.getAbsolutePath() + "/lib");
    	//
    	try {
    		properties.load(classloader.getResourceAsStream(
    				SystemUtils.class.getPackage().getName().replaceAll("[.]", "/") + "/julewa.properties"));
    		ConfigUtils.combine(isConfFile, url.openStream(), properties);
			//lp.list(System.out);
			properties.setProperty("system.path.root", PATH_ROOT);
			properties.setProperty("system.path.lib", PATH_LIB);
			properties.setProperty("system.path.classes", PATH_CLASSES);
			//
			//properties.list(System.out);
		} catch (IOException e){
			e.printStackTrace();
		}
		//
		loadLog4jConf();
		//
		debug = "true".equals(properties.getProperty("system.debug"));
    }
    
    public static boolean isDebug(){
    	return debug;
    }
    
    private static void loadLog4jConf(){
    	StringBuffer buffer = new StringBuffer();
		Set<String> keys = SystemUtils.getKeys();
		for(String k:keys){
			if(!k.startsWith("log4j."))continue;
			buffer.append(k).append("=");
			buffer.append(getProperty(k)).append("\n");
		}
		StreamUtils.saveFile(PATH_CLASSES + "log4j.properties", buffer.toString());
	}
	
    
    public static String getProperty(String key){
    	key = properties.getProperty(key);
		if(key == null){
			key = "";
		}else{
			key = key.trim();
		}
		return key;
    }
    
    public static String getProperty(String key, String defaultvalue){
    	key = properties.getProperty(key);
		if(key == null){
			return defaultvalue;
		}else{
			key = key.trim();
		}
		return key.equals("")?defaultvalue:key;
    }
    
	static String setProperty(String key, String value) {
		properties.setProperty(key, value);
		return getProperty(key);
	}
	
	static String setDefault(String key, String value) {
		String p = getProperty(key);
		if("".equals(p)){
			properties.setProperty(key, value);
			return value;
		}else{
			return p;
		}
	}
	
	@SuppressWarnings("unchecked")
	public static Set<String> getKeys(){
		return (Set)properties.keySet();
	}

	public static final String getRootPath(){
    	return PATH_ROOT;
    }
    public static final String getClassesPath(){
    	return PATH_CLASSES;
    }
    public static final String getLibPath(){
    	return PATH_LIB;
    }
    

    static final void checkDirectory(File file) throws IOException{
        if(null==file)return;
        if(!file.getParentFile().exists()){
        	checkDirectory(file.getParentFile());
        }
        if(!file.exists())file.mkdir();
    }
    static final String checkDirectory(String file) throws IOException{
    	File f = new File(file);
        checkDirectory(f);
        String p = f.getAbsolutePath();
		if(p.endsWith(FSEP))return p;
		return p + FSEP;
    }
    
	static final String getStandardPath(String path){
		File f = new File(path);
		if(f.exists() && f.isFile())return f.getAbsolutePath();
		String p = new File(path).getAbsolutePath();
		if(p.endsWith(FSEP))return p;
		return p + FSEP;
	}
	
	static final String getPathSeparator(){
		return FSEP;
	}

	public static String getPropertyName(Method method){
		String name = method.getName();
		if(name.length() < 1)return null;
		if(name.startsWith("get")){
			name = name.substring(3);
		}else if(name.startsWith("is")){
			if(Boolean.class.equals(method.getReturnType())
			|| boolean.class.equals(method.getReturnType())){
				return null;
			}
			name = name.substring(2);
		}else{
			return null;
		}
		//                                                    
		if(name.length() < 2)return name;
		if(Character.isUpperCase(name.charAt(1)))return name;
		return Character.toLowerCase(name.charAt(0)) + name.substring(1);
	}
	
	
}
